package com.zjpavt.client.extenddevice;

import com.zjpavt.client.enums.ExtendDeviceEnum;
import com.zjpavt.client.enums.ThreePhase;
import com.zjpavt.client.event.EventRegisterCenter;
import com.zjpavt.client.extenddevice.power.IPowerDevice;
import com.zjpavt.client.nativemethod.JnIMethod;
import lombok.extern.slf4j.Slf4j;

import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 远程抄表模块 电能表
 * @author zyc
 */
@Slf4j
public class PowerRemoteReader extends AbstractExtendDevice implements IPowerDevice {

    public static final Pattern POWER_PATTERN = Pattern.compile("<POWER_(?<kwh>[0-9.]+)_"+
            "\\[A/(?<AVoltage>[0-9]{1,3})/(?<ACurrent>[0-9.]{1,9})]" +
            "\\[B/(?<BVoltage>[0-9]{1,3})/(?<BCurrent>[0-9.]{1,9})]" +
            "\\[C/(?<CVoltage>[0-9]{1,3})/(?<CCurrent>[0-9.]{1,9})]" +
            "(|\\[(?<power>[0-9.]+)]"+
            "\\[(?<gridFrequency>[0-9.]+)]"+
            "\\[(?<coefficient>[0-9.]+)])>");

    /**
     * 电表总功能示数 千瓦时
     */
    private double kwh;

    /**
     * 实时功率
     */
    private double power;

    /**
     *  电网频率
     */
    private double gridFrequency;

    /**
     *  功率因数
     */
    private double coefficient;

    /**
     * a相电压
     */
    private double aVoltage;
    /**
     * b相电压
     */
    private double bVoltage;
    /**
     * c相电压
     */
    private double cVoltage;
    /**
     * a相电流
     */
    private double aCurrent;
    /**
     * b相电流
     */
    private double bCurrent;
    /**
     * c相电流
     */
    private double cCurrent;
    /**
     * @param extNum 所在拓展通道号
     */
    public PowerRemoteReader(int extNum) {
        super(extNum,ExtendDeviceEnum.POWER);
    }
    public PowerRemoteReader(int extNum,ExtendDeviceEnum extendDeviceEnum) {
        super(extNum,extendDeviceEnum);
    }

    public PowerRemoteReader updateInformation() {
        String powerInformation = JnIMethod.sendMessage2ExtendDeviceByRs485(115200, getExtendNum(), "<AT_CHECK0_POWER>", 200);
        if (powerInformation == null) {
            getUnderDeviceInteractionBean().interactionFail();
            return this;
        } else {
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put(EventRegisterCenter.DEVICE_NAME, ExtendDeviceEnum.POWER.getDeviceName());
            dataMap.put(EventRegisterCenter.EXT_NUM, getExtendNum());
            EventRegisterCenter.getInstance().triggerRegisterTask(EventRegisterCenter.DATA_EXCHANGE, dataMap);
            getUnderDeviceInteractionBean().interactionSuccess();
        }
        Matcher matcher = POWER_PATTERN.matcher(powerInformation);
        if (matcher.matches()) {
            try {
                this.kwh = Double.parseDouble(matcher.group("kwh"));
                this.aVoltage = Double.parseDouble(matcher.group("AVoltage"));
                this.bVoltage = Double.parseDouble(matcher.group("BVoltage"));
                this.cVoltage = Double.parseDouble(matcher.group("CVoltage"));
                this.aCurrent = Double.parseDouble(matcher.group("ACurrent"));
                this.bCurrent = Double.parseDouble(matcher.group("BCurrent"));
                this.cCurrent = Double.parseDouble(matcher.group("CCurrent"));
                String sPower = matcher.group("power");
                String sGridFrequency = matcher.group("gridFrequency");
                String sCoefficient = matcher.group("coefficient");
                this.power = (sPower == null) ? 0 : Double.parseDouble(sPower);
                this.gridFrequency = (sGridFrequency == null) ? 0 : Double.parseDouble(sGridFrequency);
                this.coefficient = (sCoefficient == null) ? 0 : Double.parseDouble(sCoefficient);
            } catch (NumberFormatException e) {
                log.error("update PowerRemoteReader information fail!");
            }
        } else {
            log.error("update PowerRemoteReader information fail!");
        }
        return this;
    }

    public static final DecimalFormat VOLTAGE_FORMAT = new DecimalFormat("#0");
    public static final DecimalFormat POWER_FORMAT = new DecimalFormat("#0.00");
    public static final DecimalFormat CURRENT_FORMAT = new DecimalFormat("000.0");

    @Override
    public IPowerDevice updatePowerInformation() {
        return updateInformation();
    }

    /**
     *  <W_456621.00_[A/220/000.0][B/220/000.0][C/220/000.0]_OK>
     * @return
     */
    @Override
    public String returnForWCommand() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(POWER_FORMAT.format(this.kwh))
        .append("_[A/")
        .append(VOLTAGE_FORMAT.format(aVoltage))
        .append("/")
        .append(CURRENT_FORMAT.format(aCurrent))
        .append("][B/")
        .append(VOLTAGE_FORMAT.format(bVoltage))
        .append("/")
        .append(CURRENT_FORMAT.format(bCurrent))
        .append("][C/")
        .append(VOLTAGE_FORMAT.format(cVoltage))
        .append("/")
        .append(CURRENT_FORMAT.format(cCurrent))
        .append("]");
        return stringBuilder.toString();
    }

    @Override
    public String getPhaseVoltageAndCurrent(ThreePhase threePhase) {
        switch (threePhase) {
        case A:
            return threePhase.getPhase() + "_" + getaVoltage() + "V" + getaCurrent()+ "A";
        case B:
            return threePhase.getPhase() + "_" + getbVoltage() + "V" + getbCurrent()+ "A";
        case C:
            return threePhase.getPhase() + "_" + getcVoltage() + "V" + getcCurrent()+ "A";
        default:
            return null;
        }
    }

    @Override
    public double getKwh() {
        return kwh;
    }

    @Override
    public double getPower() {
        return power;
    }

    @Override
    public double getaVoltage() {
        return aVoltage;
    }

    @Override
    public double getbVoltage() {
        return bVoltage;
    }

    @Override
    public double getcVoltage() {
        return cVoltage;
    }

    @Override
    public double getaCurrent() {
        return aCurrent;
    }

    @Override
    public double getbCurrent() {
        return bCurrent;
    }

    @Override
    public double getcCurrent() {
        return cCurrent;
    }

    @Override
    public double getGridFrequency() {
        return gridFrequency;
    }

    @Override
    public double getCoefficient() {
        return coefficient;
    }
}

